package org.platform.lwc.gateway.service.impl;

import cn.hutool.core.convert.Convert;
import org.platform.lwc.gateway.service.ResourceService;
import org.platform.lwc.redis.utils.RedisUtil;
import org.platform.lwc.system.feign.ISysMenuClient;
import org.platform.lwc.system.vo.MenuPathSocietyRoleKeyVO;
import org.platform.lwc.tool.api.R;
import org.platform.lwc.tool.auth.constants.AuthConstant;
import org.platform.lwc.tool.auth.utils.AuthUtil;
import org.platform.lwc.tool.utils.StringPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 资源与角色匹配关系管理业务类
 */
@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ISysMenuClient sysMenuClient;

    @Autowired(required = false)
    private RedisUtil redisUtil;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public List<String> getRolesByRedisOrDb(URI uri) {
        // 需要处理url才能获取redis里面的对应的值
        String urlHandle = AuthUtil.getStrHandle(uri.getPath(), StringPool.SLASH, 2);
        //根据key查看缓存是否有缓存菜单
        if (redisUtil.hasKey(AuthConstant.RESOURCE_ROLES_MAP)) {
            //todo 存在key
            //从Redis中获取当前路径可访问角色列表
            Object obj = redisUtil.hget(AuthConstant.RESOURCE_ROLES_MAP, urlHandle);
            return Convert.toList(String.class, obj);
        }
        //todo 不存在
        return getRolesByDb(urlHandle);

    }

    /**
     * description: 数据库中查询全部菜单并存入缓存 返回url对应的roles (只有Redis没有key才会进入,所以给角色授权菜单需要删除这个key)
     *
     * @author lwc
     * @date 2022/4/9
     */
    private List<String> getRolesByDb(String urlHandle) {
        R<List<MenuPathSocietyRoleKeyVO>> r = sysMenuClient.getMenuPathSocietyRoleKey();
        if (r.isSuccess()) {
            Map<String, List<String>> collect = r.getData().stream()
                    .collect(
                            Collectors.groupingBy(MenuPathSocietyRoleKeyVO::getPath,
                                    Collectors.mapping(MenuPathSocietyRoleKeyVO::getRoleKey, Collectors.toList()))
                    );
            redisTemplate.opsForHash().putAll(AuthConstant.RESOURCE_ROLES_MAP, collect);
        }
        //从Redis中获取当前路径可访问角色列表
        Object obj = redisUtil.hget(AuthConstant.RESOURCE_ROLES_MAP, urlHandle);
        return Convert.toList(String.class, obj);
    }
}
